package cn.mesmile.design.prototype;

import java.io.*;

/**
 * @author zb
 * @date 2020/11/15 14:34
 * @Description: 【 创建型设计模式-原型设计模式Prototype】
 *
 *  核心组成
 *
 *  Prototype: 声明克隆方法的接口,是所有具体原型类的公共父类，Cloneable接口
 *  ConcretePrototype : 具体原型类
 *  Client: 让一个原型对象克隆自身从而创建一个新的对象
 */
public class Person implements Cloneable, Serializable {

    private String name;

    private int age;

    public Person() {
        System.out.println(">>>>>>> 构造方法被调用");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    /**
     *  【浅拷贝】
     *   如果原型对象的成员变量是基本数据类型（int、double、byte、boolean、char等），
     *   将复制一份给克隆对象；
     *   如果原型对象的成员变量是引用类型，则将引用对象的地址复制一份给克隆对象，
     *   也就是说原型对象和克隆对象的成员变量指向相同的内存地址
     * ​
     *   通过覆盖Object类的clone()方法可以实现浅克隆
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }


    /**
     *  【深拷贝】
     * 无论原型对象的成员变量是基本数据类型还是引用类型，都将复制一份给克隆对象，
     * 如果需要实现深克隆，可以通过序列化(Serializable)等方式来实现
     * @return
     */
    protected Person deepClone() {

        try {
            // 输出  序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(oos);

            // 输入 反序列化
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            Person copyPerson = (Person) ois.readObject();

            return copyPerson;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }


}
